﻿using System;
using System.Windows.Forms;
using InputHandlers.KeyboardHandling;
using NUnit.Framework;

namespace CryptoQrUtilities.UnitTests
{
    [TestFixture]
    public class ToggleKeyTests
    {
        [Test]
        public void BasicToggleKeyTest()
        {
            var toggleKey = new ToggleKey(Keys.Alt, delegate { });

            Assert.IsFalse(toggleKey.On, "'On' property, test 1");
            Assert.AreEqual(Keys.Alt, toggleKey.KeyDefinition, "'KeyDefinition' property, test 1.");

            toggleKey = new ToggleKey(Keys.Alt, delegate { }, true);

            Assert.IsTrue(toggleKey.On, "'On' property, test 2");
            Assert.AreEqual(Keys.Alt, toggleKey.KeyDefinition, "'KeyDefinition' property, test 2.");
        }

        [Test]
        public void ToggleBasicKeyTest()
        {
            var toggleKey = new ToggleKey(Keys.A, delegate { });

            toggleKey.ToggleState();
            Assert.IsTrue(toggleKey.On, "Toggle once.");
            toggleKey.ToggleState();
            Assert.IsFalse(toggleKey.On, "Toggle twice.");
            toggleKey.ToggleState(true);
            Assert.IsTrue(toggleKey.On, "Set state 'true'.");
            toggleKey.ToggleState(false);
            Assert.IsFalse(toggleKey.On, "Set state 'false'.");
        }

        [Test]
        public void VerifyBasicPredicateCheckTest()
        {
            var toggleKey = new ToggleKey(Keys.A, delegate { });

            Assert.IsTrue(toggleKey.CheckContained(Keys.A));
            Assert.IsFalse(toggleKey.CheckContained(Keys.B));
        }

        [Test]
        public void VerifyExtendedToggleKeyCreationLimitationTest()
        {
            bool caughtRightException = false;

            try
            {
                var extendedToggleKey = new ExtendedToggleKey(Keys.A, delegate { });
            }
            catch (Exception ex)
            {
                if (ex.GetType() == typeof(ArgumentException))
                {
                    caughtRightException = true;
                }
            }

            Assert.IsTrue(caughtRightException, "Expected exception was not caught.");
        }

        [Test]
        public void VerifyAltPredicateCheckTest()
        {
            var exToggleKey = new ExtendedToggleKey(Keys.Alt, delegate { });

            Assert.IsTrue(exToggleKey.CheckContained(Keys.Alt), "Alt presence in input.");
            Assert.IsFalse(exToggleKey.CheckContained(Keys.A), "Alt not present in input.");
            Assert.IsTrue(exToggleKey.CheckContained(Keys.Shift | Keys.Alt), "Alt is part of a key combination");
        }

        [Test]
        public void VerifyControlPredicateCheckTest()
        {
            var exToggleKey = new ExtendedToggleKey(Keys.Control, delegate { });

            Assert.IsTrue(exToggleKey.CheckContained(Keys.Control), "Control presence in input.");
            Assert.IsFalse(exToggleKey.CheckContained(Keys.A), "Control not present in input.");
            Assert.IsTrue(exToggleKey.CheckContained(Keys.Shift | Keys.Control), "Control is part of a key combination");
        }

        [Test]
        public void VerifyShiftPredicateCheckTest()
        {
            var exToggleKey = new ExtendedToggleKey(Keys.Shift, delegate { });

            Assert.IsTrue(exToggleKey.CheckContained(Keys.Shift), "Shift presence in input.");
            Assert.IsFalse(exToggleKey.CheckContained(Keys.A), "Shift not present in input.");
            Assert.IsTrue(exToggleKey.CheckContained(Keys.Shift | Keys.Control), "Shift is part of a key combination");
        }
    }
}

